package com.tsc.springTemp.springBeanLifeModel;
import org.springframework.beans.factory.BeanFactory;

import java.lang.reflect.Method;
import java.util.*;
/**
 * Created with IntelliJ IDEA.
 *
 * @Author: chentl
 * @Date: 2025/09/12/12:17
 * @Description:
 */


public class MyApplicationContext implements ApplicationContext {

    private Map<String, Object> beans = new HashMap<>();
    private Map<String, Class<?>> beanDefinitions = new HashMap<>();
    private List<BeanPostProcessor> postProcessors = new ArrayList<>();

    public MyApplicationContext() {
        // 注册 Bean 定义
        beanDefinitions.put("userService", UserService.class);
        postProcessors.add(new MyBeanPostProcessor());
    }


    public Object getBean(String name) {
        if (beans.containsKey(name)) {
            return beans.get(name);
        }
        return createBean(name, beanDefinitions.get(name));
    }

    private Object createBean(String beanName, Class<?> beanClass) {
        try {
            // 1. 实例化
            Object bean = beanClass.getDeclaredConstructor().newInstance();
            System.out.println("=== 开始创建 Bean: " + beanName + " ===");

            // 2. 属性赋值
            if (bean instanceof UserService) {
                ((UserService) bean).setUsername("John Doe");
            }

            // 3. Aware 接口调用
            invokeAwareInterfaces(bean, beanName);

            // 4. BeanPostProcessor.postProcessBeforeInitialization
            for (BeanPostProcessor processor : postProcessors) {
                bean = processor.postProcessBeforeInitialization(bean, beanName);
            }

            // 5. 初始化方法
            invokeInitMethods(bean);

            // 6. BeanPostProcessor.postProcessAfterInitialization
            for (BeanPostProcessor processor : postProcessors) {
                bean = processor.postProcessAfterInitialization(bean, beanName);
            }

            beans.put(beanName, bean);
            System.out.println("=== Bean 创建完成 ===");
            return bean;

        } catch (Exception e) {
            throw new RuntimeException("创建 Bean 失败: " + beanName, e);
        }
    }

    private void invokeAwareInterfaces(Object bean, String beanName) {
        if (bean instanceof BeanNameAware) {
            ((BeanNameAware) bean).setBeanName(beanName);
        }
//        if (bean instanceof BeanFactoryAware) {
//            ((BeanFactoryAware) bean).setBeanFactory((BeanFactory) this);
//        }
//        if (bean instanceof ApplicationContextAware) {
//            ((ApplicationContextAware) bean).setApplicationContext(this);
//        }
    }

    private void invokeInitMethods(Object bean) throws Exception {
        // 调用 @PostConstruct 方法
        for (Method method : bean.getClass().getMethods()) {
            if (method.isAnnotationPresent(PostConstruct.class)) {
                method.invoke(bean);
            }
        }

        // 调用 InitializingBean.afterPropertiesSet
        if (bean instanceof InitializingBean) {
            ((InitializingBean) bean).afterPropertiesSet();
        }

        // 调用自定义 init-method (这里固定调用 customInit)
        if (bean instanceof UserService) {
            ((UserService) bean).customInit();
        }
    }

    @Override
    public void close() {
        System.out.println("\n=== 容器开始关闭 ===");
        for (Object bean : beans.values()) {
            invokeDestroyMethods(bean);
        }
        beans.clear();
        System.out.println("=== 容器关闭完成 ===");
    }

    private void invokeDestroyMethods(Object bean) {
        try {
            // 调用 @PreDestroy 方法
            for (Method method : bean.getClass().getMethods()) {
                if (method.isAnnotationPresent(PreDestroy.class)) {
                    method.invoke(bean);
                }
            }

            // 调用 DisposableBean.destroy
            if (bean instanceof DisposableBean) {
                ((DisposableBean) bean).destroy();
            }

            // 调用自定义 destroy-method
            if (bean instanceof UserService) {
                ((UserService) bean).customDestroy();
            }
        } catch (Exception e) {
            System.err.println("调用销毁方法失败: " + e.getMessage());
        }
    }
}
